home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume21 / amd / part04 < prev    next >
Encoding:
Internet Message Format  |  1990-04-10  |  51.7 KB

  1. Subject:  v21i092:  An Automounter for NFS systems, Part04/13
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: ac520e2c 91ff7e99 185b47fc 54e5ad2f
  5.  
  6. Submitted-by: Jan-Simon Pendry <jsp@doc.ic.ac.uk>
  7. Posting-number: Volume 21, Issue 92
  8. Archive-name: amd/part04
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 4 (of 13)."
  17. # Contents:  amq.x amq_xdr.c clock.c doc/amd.bib doc/nh.doc info_file.c
  18. #   mount_fs.c nfs_prot_svc.c restart.c sched.c
  19. # Wrapped by rsalz@papaya.bbn.com on Tue Apr 10 15:12:02 1990
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'amq.x' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'amq.x'\"
  23. else
  24. echo shar: Extracting \"'amq.x'\" \(4120 characters\)
  25. sed "s/^X//" >'amq.x' <<'END_OF_FILE'
  26. X/*
  27. X * $Id: amq.x,v 5.1.1.1 90/01/11 17:02:14 jsp Exp Locker: jsp $
  28. X *
  29. X * Copyright (c) 1990 Jan-Simon Pendry
  30. X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  31. X * Copyright (c) 1990 The Regents of the University of California.
  32. X * All rights reserved.
  33. X *
  34. X * This code is derived from software contributed to Berkeley by
  35. X * Jan-Simon Pendry at Imperial College, London.
  36. X *
  37. X * Redistribution and use in source and binary forms are permitted
  38. X * provided that the above copyright notice and this paragraph are
  39. X * duplicated in all such forms and that any documentation,
  40. X * advertising materials, and other materials related to such
  41. X * distribution and use acknowledge that the software was developed
  42. X * by Imperial College of Science, Technology and Medicine, London, UK.
  43. X * The names of the College and University may not be used to endorse
  44. X * or promote products derived from this software without specific
  45. X * prior written permission.
  46. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  47. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  48. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  49. X *
  50. X *    %W% (Berkeley) %G%
  51. X */
  52. X
  53. X/*
  54. X * Protocol description used by the amq program
  55. X */
  56. X
  57. Xconst AMQ_STRLEN = 1024;    /* Maximum length of a pathname */
  58. X
  59. X/*
  60. X * The type dirpath is the pathname of a directory
  61. X */
  62. Xtypedef string amq_string<AMQ_STRLEN>;
  63. X
  64. X/*
  65. X * The type time_type should correspond to the system time_t
  66. X */
  67. Xtypedef long time_type;
  68. X
  69. X/*
  70. X * A tree of what is mounted
  71. X */
  72. Xstruct amq_mount_tree {
  73. X    amq_string    mt_mountinfo;    /* Mounted filesystem */
  74. X    amq_string     mt_directory;    /* Virtual mount */
  75. X    amq_string     mt_mountpoint;    /* Mount point */
  76. X    amq_string    mt_type;    /* Filesystem type */
  77. X    time_type    mt_mounttime;    /* Mount time */
  78. X    u_short        mt_mountuid;    /* Mounter */
  79. X    int        mt_getattr;    /* Count of getattrs */
  80. X    int        mt_lookup;    /* Count of lookups */
  81. X    int        mt_readdir;    /* Count of readdirs */
  82. X    int        mt_readlink;    /* Count of readlinks */
  83. X    int        mt_statfs;    /* Count of statfss */
  84. X    amq_mount_tree    *mt_next;    /* Sibling mount tree */
  85. X    amq_mount_tree    *mt_child;    /* Child mount tree */
  86. X};
  87. Xtypedef amq_mount_tree *amq_mount_tree_p;
  88. X
  89. X/*
  90. X * List of mounted filesystems
  91. X */
  92. Xstruct amq_mount_info {
  93. X    amq_string    mi_type;    /* Type of mount */
  94. X    amq_string    mi_mountpt;    /* Mount point */
  95. X    amq_string    mi_mountinfo;    /* Mount info */
  96. X    amq_string    mi_fserver;    /* Fileserver */
  97. X    int        mi_error;    /* Error code */
  98. X    int        mi_refc;    /* References */
  99. X    int        mi_up;        /* Filesystem available */
  100. X};
  101. Xtypedef amq_mount_info amq_mount_info_list<>;
  102. X
  103. X/*
  104. X * A list of mount trees
  105. X */
  106. Xtypedef amq_mount_tree_p amq_mount_tree_list<>;
  107. X
  108. X/*
  109. X * System wide stats
  110. X */
  111. Xstruct amq_mount_stats {
  112. X    int    as_drops;    /* Dropped requests */
  113. X    int    as_stale;    /* Stale NFS handles */
  114. X    int    as_mok;        /* Succesful mounts */
  115. X    int    as_merr;    /* Failed mounts */
  116. X    int    as_uerr;    /* Failed unmounts */
  117. X};
  118. X
  119. Xenum amq_opt {
  120. X    AMOPT_DEBUG=0,
  121. X    AMOPT_LOGFILE=1,
  122. X    AMOPT_XLOG=2,
  123. X    AMOPT_FLUSHMAPC=3
  124. X};
  125. X
  126. Xstruct amq_setopt {
  127. X    amq_opt    as_opt;        /* Option */
  128. X    amq_string as_str;    /* String */
  129. X};
  130. X
  131. Xprogram AMQ_PROGRAM {
  132. X    version AMQ_VERSION {
  133. X        /*
  134. X         * Does no work. It is made available in all RPC services
  135. X         * to allow server reponse testing and timing
  136. X         */
  137. X        void
  138. X        AMQPROC_NULL(void) = 0;
  139. X
  140. X        /*
  141. X         * Returned the mount tree descending from
  142. X         * the given directory.  The directory must
  143. X         * be a top-level mount point of the automounter.
  144. X         */
  145. X        amq_mount_tree_p
  146. X        AMQPROC_MNTTREE(amq_string) = 1;
  147. X
  148. X        /*
  149. X         * Force a timeout unmount on the specified directory.
  150. X         */
  151. X        void
  152. X        AMQPROC_UMNT(amq_string) = 2;
  153. X
  154. X        /*
  155. X         * Obtain system wide statistics from the automounter
  156. X         */
  157. X        amq_mount_stats
  158. X        AMQPROC_STATS(void) = 3;
  159. X
  160. X        /*
  161. X         * Obtain full tree
  162. X         */
  163. X        amq_mount_tree_list
  164. X        AMQPROC_EXPORT(void) = 4;
  165. X
  166. X        /*
  167. X         * Control debug options.
  168. X         * Return status:
  169. X         *    -1: debug not available
  170. X         *     0: everything wonderful
  171. X         *    >0: number of options not recognised
  172. X         */
  173. X        int
  174. X        AMQPROC_SETOPT(amq_setopt) = 5;
  175. X
  176. X        /*
  177. X         * List of mounted filesystems
  178. X         */
  179. X        amq_mount_info_list
  180. X        AMQPROC_GETMNTFS(void) = 6;
  181. X    } = 1;
  182. X} = 300019;    /* Allocated by Sun, 89/8/29 */
  183. END_OF_FILE
  184. if test 4120 -ne `wc -c <'amq.x'`; then
  185.     echo shar: \"'amq.x'\" unpacked with wrong size!
  186. fi
  187. # end of 'amq.x'
  188. fi
  189. if test -f 'amq_xdr.c' -a "${1}" != "-c" ; then 
  190.   echo shar: Will not clobber existing file \"'amq_xdr.c'\"
  191. else
  192. echo shar: Extracting \"'amq_xdr.c'\" \(4678 characters\)
  193. sed "s/^X//" >'amq_xdr.c' <<'END_OF_FILE'
  194. X/*
  195. X * $Id: amq_xdr.c,v 5.1.1.1 90/01/11 17:04:23 jsp Exp Locker: jsp $
  196. X *
  197. X * Copyright (c) 1990 Jan-Simon Pendry
  198. X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  199. X * Copyright (c) 1990 The Regents of the University of California.
  200. X * All rights reserved.
  201. X *
  202. X * This code is derived from software contributed to Berkeley by
  203. X * Jan-Simon Pendry at Imperial College, London.
  204. X *
  205. X * Redistribution and use in source and binary forms are permitted
  206. X * provided that the above copyright notice and this paragraph are
  207. X * duplicated in all such forms and that any documentation,
  208. X * advertising materials, and other materials related to such
  209. X * distribution and use acknowledge that the software was developed
  210. X * by Imperial College of Science, Technology and Medicine, London, UK.
  211. X * The names of the College and University may not be used to endorse
  212. X * or promote products derived from this software without specific
  213. X * prior written permission.
  214. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  215. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  216. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  217. X *
  218. X *    %W% (Berkeley) %G%
  219. X */
  220. X
  221. X#include "am.h"
  222. X#include "amq.h"
  223. X
  224. X
  225. Xbool_t
  226. Xxdr_amq_string(xdrs, objp)
  227. X    XDR *xdrs;
  228. X    amq_string *objp;
  229. X{
  230. X    if (!xdr_string(xdrs, objp, AMQ_STRLEN)) {
  231. X        return (FALSE);
  232. X    }
  233. X    return (TRUE);
  234. X}
  235. X
  236. X
  237. X
  238. X
  239. Xbool_t
  240. Xxdr_time_type(xdrs, objp)
  241. X    XDR *xdrs;
  242. X    time_type *objp;
  243. X{
  244. X    if (!xdr_long(xdrs, objp)) {
  245. X        return (FALSE);
  246. X    }
  247. X    return (TRUE);
  248. X}
  249. X
  250. X
  251. X
  252. X
  253. Xbool_t
  254. Xxdr_amq_mount_tree(xdrs, objp)
  255. X    XDR *xdrs;
  256. X    amq_mount_tree *objp;
  257. X{
  258. X    if (!xdr_amq_string(xdrs, &objp->mt_mountinfo)) {
  259. X        return (FALSE);
  260. X    }
  261. X    if (!xdr_amq_string(xdrs, &objp->mt_directory)) {
  262. X        return (FALSE);
  263. X    }
  264. X    if (!xdr_amq_string(xdrs, &objp->mt_mountpoint)) {
  265. X        return (FALSE);
  266. X    }
  267. X    if (!xdr_amq_string(xdrs, &objp->mt_type)) {
  268. X        return (FALSE);
  269. X    }
  270. X    if (!xdr_time_type(xdrs, &objp->mt_mounttime)) {
  271. X        return (FALSE);
  272. X    }
  273. X    if (!xdr_u_short(xdrs, &objp->mt_mountuid)) {
  274. X        return (FALSE);
  275. X    }
  276. X    if (!xdr_int(xdrs, &objp->mt_getattr)) {
  277. X        return (FALSE);
  278. X    }
  279. X    if (!xdr_int(xdrs, &objp->mt_lookup)) {
  280. X        return (FALSE);
  281. X    }
  282. X    if (!xdr_int(xdrs, &objp->mt_readdir)) {
  283. X        return (FALSE);
  284. X    }
  285. X    if (!xdr_int(xdrs, &objp->mt_readlink)) {
  286. X        return (FALSE);
  287. X    }
  288. X    if (!xdr_int(xdrs, &objp->mt_statfs)) {
  289. X        return (FALSE);
  290. X    }
  291. X    if (!xdr_pointer(xdrs, (char **)&objp->mt_next, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
  292. X        return (FALSE);
  293. X    }
  294. X    if (!xdr_pointer(xdrs, (char **)&objp->mt_child, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
  295. X        return (FALSE);
  296. X    }
  297. X    return (TRUE);
  298. X}
  299. X
  300. X
  301. X
  302. X
  303. Xbool_t
  304. Xxdr_amq_mount_tree_p(xdrs, objp)
  305. X    XDR *xdrs;
  306. X    amq_mount_tree_p *objp;
  307. X{
  308. X    if (!xdr_pointer(xdrs, (char **)objp, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
  309. X        return (FALSE);
  310. X    }
  311. X    return (TRUE);
  312. X}
  313. X
  314. X
  315. X
  316. Xbool_t
  317. Xxdr_amq_mount_info(xdrs, objp)
  318. X    XDR *xdrs;
  319. X    amq_mount_info *objp;
  320. X{
  321. X    if (!xdr_amq_string(xdrs, &objp->mi_type)) {
  322. X        return (FALSE);
  323. X    }
  324. X    if (!xdr_amq_string(xdrs, &objp->mi_mountpt)) {
  325. X        return (FALSE);
  326. X    }
  327. X    if (!xdr_amq_string(xdrs, &objp->mi_mountinfo)) {
  328. X        return (FALSE);
  329. X    }
  330. X    if (!xdr_amq_string(xdrs, &objp->mi_fserver)) {
  331. X        return (FALSE);
  332. X    }
  333. X    if (!xdr_int(xdrs, &objp->mi_error)) {
  334. X        return (FALSE);
  335. X    }
  336. X    if (!xdr_int(xdrs, &objp->mi_refc)) {
  337. X        return (FALSE);
  338. X    }
  339. X    if (!xdr_int(xdrs, &objp->mi_up)) {
  340. X        return (FALSE);
  341. X    }
  342. X    return (TRUE);
  343. X}
  344. X
  345. X
  346. X
  347. Xbool_t
  348. Xxdr_amq_mount_info_list(xdrs, objp)
  349. X    XDR *xdrs;
  350. X    amq_mount_info_list *objp;
  351. X{
  352. X    if (!xdr_array(xdrs, (char **)&objp->amq_mount_info_list_val, (u_int *)&objp->amq_mount_info_list_len, ~0, sizeof(amq_mount_info), xdr_amq_mount_info)) {
  353. X        return (FALSE);
  354. X    }
  355. X    return (TRUE);
  356. X}
  357. X
  358. X
  359. X
  360. Xbool_t
  361. Xxdr_amq_mount_tree_list(xdrs, objp)
  362. X    XDR *xdrs;
  363. X    amq_mount_tree_list *objp;
  364. X{
  365. X    if (!xdr_array(xdrs, (char **)&objp->amq_mount_tree_list_val, (u_int *)&objp->amq_mount_tree_list_len, ~0, sizeof(amq_mount_tree_p), xdr_amq_mount_tree_p)) {
  366. X        return (FALSE);
  367. X    }
  368. X    return (TRUE);
  369. X}
  370. X
  371. X
  372. X
  373. X
  374. Xbool_t
  375. Xxdr_amq_mount_stats(xdrs, objp)
  376. X    XDR *xdrs;
  377. X    amq_mount_stats *objp;
  378. X{
  379. X    if (!xdr_int(xdrs, &objp->as_drops)) {
  380. X        return (FALSE);
  381. X    }
  382. X    if (!xdr_int(xdrs, &objp->as_stale)) {
  383. X        return (FALSE);
  384. X    }
  385. X    if (!xdr_int(xdrs, &objp->as_mok)) {
  386. X        return (FALSE);
  387. X    }
  388. X    if (!xdr_int(xdrs, &objp->as_merr)) {
  389. X        return (FALSE);
  390. X    }
  391. X    if (!xdr_int(xdrs, &objp->as_uerr)) {
  392. X        return (FALSE);
  393. X    }
  394. X    return (TRUE);
  395. X}
  396. X
  397. X
  398. X
  399. X
  400. Xbool_t
  401. Xxdr_amq_opt(xdrs, objp)
  402. X    XDR *xdrs;
  403. X    amq_opt *objp;
  404. X{
  405. X    if (!xdr_enum(xdrs, (enum_t *)objp)) {
  406. X        return (FALSE);
  407. X    }
  408. X    return (TRUE);
  409. X}
  410. X
  411. X
  412. X
  413. X
  414. Xbool_t
  415. Xxdr_amq_setopt(xdrs, objp)
  416. X    XDR *xdrs;
  417. X    amq_setopt *objp;
  418. X{
  419. X    if (!xdr_amq_opt(xdrs, &objp->as_opt)) {
  420. X        return (FALSE);
  421. X    }
  422. X    if (!xdr_amq_string(xdrs, &objp->as_str)) {
  423. X        return (FALSE);
  424. X    }
  425. X    return (TRUE);
  426. X}
  427. X
  428. X
  429. END_OF_FILE
  430. if test 4678 -ne `wc -c <'amq_xdr.c'`; then
  431.     echo shar: \"'amq_xdr.c'\" unpacked with wrong size!
  432. fi
  433. # end of 'amq_xdr.c'
  434. fi
  435. if test -f 'clock.c' -a "${1}" != "-c" ; then 
  436.   echo shar: Will not clobber existing file \"'clock.c'\"
  437. else
  438. echo shar: Extracting \"'clock.c'\" \(4452 characters\)
  439. sed "s/^X//" >'clock.c' <<'END_OF_FILE'
  440. X/*
  441. X * $Id: clock.c,v 5.1 89/11/17 18:19:50 jsp Exp Locker: jsp $
  442. X *
  443. X * Copyright (c) 1989 Jan-Simon Pendry
  444. X * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  445. X * Copyright (c) 1989 The Regents of the University of California.
  446. X * All rights reserved.
  447. X *
  448. X * This code is derived from software contributed to Berkeley by
  449. X * Jan-Simon Pendry at Imperial College, London.
  450. X *
  451. X * Redistribution and use in source and binary forms are permitted
  452. X * provided that the above copyright notice and this paragraph are
  453. X * duplicated in all such forms and that any documentation,
  454. X * advertising materials, and other materials related to such
  455. X * distribution and use acknowledge that the software was developed
  456. X * by Imperial College of Science, Technology and Medicine, London, UK.
  457. X * The names of the College and University may not be used to endorse
  458. X * or promote products derived from this software without specific
  459. X * prior written permission.
  460. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  461. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  462. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  463. X *
  464. X *    %W% (Berkeley) %G%
  465. X */
  466. X
  467. X/*
  468. X * Callouts.
  469. X *
  470. X * Modelled on kernel object of the same name.
  471. X * See usual references.
  472. X *
  473. X * Use of a heap-based mechanism was rejected:
  474. X * 1.  more complext implementation needed.
  475. X * 2.  not obvious that a list is too slow for amd.
  476. X */
  477. X
  478. X#include "am.h"
  479. X
  480. Xtypedef struct callout callout;
  481. Xstruct callout {
  482. X    callout    *c_next;        /* List of callouts */
  483. X    void    (*c_fn)();        /* Function to call */
  484. X    voidp    c_closure;        /* Closure to pass to call */
  485. X    time_t    c_time;            /* Time of call */
  486. X    int    c_id;            /* Unique identifier */
  487. X};
  488. X
  489. Xstatic callout callouts;        /* List of pending callouts */
  490. Xstatic callout *free_callouts;        /* Cache of free callouts */
  491. Xstatic int nfree_callouts;        /* Number on free list */
  492. Xstatic int callout_id;            /* Next free callout identifier */
  493. Xtime_t next_softclock;            /* Time of next call to softclock() */
  494. X
  495. X/*
  496. X * Number of callout slots we keep on the free list
  497. X */
  498. X#define    CALLOUT_FREE_SLOP    10
  499. X
  500. X/*
  501. X * Assumption: valid id's are non-zero.
  502. X */
  503. X#define    CID_ALLOC()    (++callout_id)
  504. X#define    CID_UNDEF    (0)
  505. X
  506. Xstatic callout *alloc_callout()
  507. X{
  508. X    callout *cp = free_callouts;
  509. X    if (cp) {
  510. X        --nfree_callouts;
  511. X        free_callouts = free_callouts->c_next;
  512. X        return cp;
  513. X    }
  514. X    return ALLOC(callout);
  515. X}
  516. X
  517. Xstatic void free_callout(cp)
  518. Xcallout *cp;
  519. X{
  520. X    if (nfree_callouts > CALLOUT_FREE_SLOP) {
  521. X        free((voidp) cp);
  522. X    } else {
  523. X        cp->c_next = free_callouts;
  524. X        free_callouts = cp;
  525. X        nfree_callouts++;
  526. X    }
  527. X}
  528. X
  529. X/*
  530. X * Schedule a callout.
  531. X *
  532. X * (*fn)(closure) will be called at clocktime() + secs
  533. X */
  534. Xint timeout(secs, fn, closure)
  535. Xunsigned int secs;
  536. Xvoid (*fn)();
  537. Xvoidp closure;
  538. X{
  539. X    callout *cp, *cp2;
  540. X    time_t t = clocktime() + secs;
  541. X
  542. X    /*
  543. X     * Allocate and fill in a new callout structure
  544. X     */
  545. X    callout *cpnew = alloc_callout();
  546. X    cpnew->c_closure = closure;
  547. X    cpnew->c_fn = fn;
  548. X    cpnew->c_time = t;
  549. X    cpnew->c_id = CID_ALLOC();
  550. X
  551. X    if (t < next_softclock)
  552. X        next_softclock = t;
  553. X
  554. X    /*
  555. X     * Find the correct place in the list
  556. X     */
  557. X    for (cp = &callouts; cp2 = cp->c_next; cp = cp2)
  558. X        if (cp2->c_time >= t)
  559. X            break;
  560. X
  561. X    /*
  562. X     * And link it in
  563. X     */
  564. X    cp->c_next = cpnew;
  565. X    cpnew->c_next = cp2;
  566. X
  567. X    /*
  568. X     * Return callout identifier
  569. X     */
  570. X    return cpnew->c_id;
  571. X}
  572. X
  573. X/*
  574. X * De-schedule a callout
  575. X */
  576. Xvoid untimeout(id)
  577. Xint id;
  578. X{
  579. X    callout *cp, *cp2;
  580. X    for (cp = &callouts; cp2 = cp->c_next; cp = cp2) {
  581. X        if (cp2->c_id == id) {
  582. X            cp->c_next = cp2->c_next;
  583. X            free_callout(cp2);
  584. X            break;
  585. X        }
  586. X    }
  587. X}
  588. X
  589. X/*
  590. X * Clock handler
  591. X */
  592. Xint softclock()
  593. X{
  594. X    time_t now;
  595. X    callout *cp;
  596. X
  597. X    do {
  598. X        if (task_notify_todo)
  599. X            task_notify();
  600. X
  601. X        now = clocktime();
  602. X
  603. X        /*
  604. X         * While there are more callouts waiting...
  605. X         */
  606. X        while ((cp = callouts.c_next) && cp->c_time <= now) {
  607. X            /*
  608. X             * Extract first from list, save fn & closure and
  609. X             * unlink callout from list and free.
  610. X             * Finally call function.
  611. X             *
  612. X             * The free is done first because
  613. X             * it is quite common that the
  614. X             * function will call timeout()
  615. X             * and try to allocate a callout
  616. X             */
  617. X            void (*fn)() = cp->c_fn;
  618. X            voidp closure = cp->c_closure;
  619. X
  620. X            callouts.c_next = cp->c_next;
  621. X            free_callout(cp);
  622. X#ifdef DEBUG
  623. X            /*dlog("Calling %#x(%#x)", fn, closure);*/
  624. X#endif
  625. X            (*fn)(closure);
  626. X        }
  627. X
  628. X    } while (task_notify_todo);
  629. X
  630. X    /*
  631. X     * Return number of seconds to next event,
  632. X     * or 0 if there is no event.
  633. X     */
  634. X    if (cp = callouts.c_next)
  635. X        return cp->c_time - now;
  636. X    return 0;
  637. X}
  638. END_OF_FILE
  639. if test 4452 -ne `wc -c <'clock.c'`; then
  640.     echo shar: \"'clock.c'\" unpacked with wrong size!
  641. fi
  642. # end of 'clock.c'
  643. fi
  644. if test -f 'doc/amd.bib' -a "${1}" != "-c" ; then 
  645.   echo shar: Will not clobber existing file \"'doc/amd.bib'\"
  646. else
  647. echo shar: Extracting \"'doc/amd.bib'\" \(3898 characters\)
  648. sed "s/^X//" >'doc/amd.bib' <<'END_OF_FILE'
  649. X% $Id: amd.bib,v 5.1 89/11/17 18:24:37 jsp Exp Locker: jsp $
  650. X%
  651. X% Copyright (c) 1989 Jan-Simon Pendry
  652. X% Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  653. X% Copyright (c) 1989 The Regents of the University of California.
  654. X% All rights reserved.
  655. X%
  656. X% This code is derived from software contributed to Berkeley by
  657. X% Jan-Simon Pendry at Imperial College, London.
  658. X%
  659. X% Redistribution and use in source and binary forms are permitted
  660. X% provided that the above copyright notice and this paragraph are
  661. X% duplicated in all such forms and that any documentation,
  662. X% advertising materials, and other materials related to such
  663. X% distribution and use acknowledge that the software was developed
  664. X% by Imperial College of Science, Technology and Medicine, London, UK.
  665. X% The names of the College and University may not be used to endorse
  666. X% or promote products derived from this software without specific
  667. X% prior written permission.
  668. X% THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  669. X% IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  670. X% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  671. X%
  672. X%    %W% (Berkeley) %G%
  673. X
  674. X@inproceedings{usenix:automounter
  675. X    ,author =    "Brent Callaghan and Tom Lyon"
  676. X    ,month =    "January"
  677. X    ,year =        "1989"
  678. X    ,title =    "{The Automounter}"
  679. X    ,booktitle =    "Usenix Conference Proceedings, {\rm San Diego, California}"
  680. X    ,organization = "Usenix Association"
  681. X    ,pages =    "43-51"
  682. X}
  683. X
  684. X@inproceedings{mit:hesiod
  685. X    ,author =    "Stephen P. Dyer"
  686. X    ,title =    "{The {\em Hesiod} Name Server}"
  687. X    ,booktitle =    "Usenix Conference Proceedings, {\rm Dallas, Texas}"
  688. X    ,year =        "1988"
  689. X    ,month =    "February"
  690. X    ,organization = "Usenix Association"
  691. X    ,pages =    "183--189"
  692. X}
  693. X
  694. X@techreport{mit:rvd
  695. X    ,author =    "M. Greenwald and J. V. Sciver"
  696. X    ,title =    "{Remote Virtual Disk Protocol Specification}"
  697. X    ,year =        "1986"
  698. X    ,institution =    "Massachusetts Institute of Technology"
  699. X    ,address =    "Cambridge, Massachusetts"
  700. X}
  701. X
  702. X@inbook{bsd:ufs
  703. X    ,author =    "Samuel J. Leffler and others"
  704. X    ,year =        "1989"
  705. X    ,title =    "The Design and Implementation of the 4.3BSD UNIX Operating System"
  706. X    ,chapter =    "7"
  707. X    ,pages =    "187--223"
  708. X    ,publisher =    "Addison-Wesley"
  709. X}
  710. X
  711. X@techreport{rfc:icmp
  712. X    ,author =    "J. Postel"
  713. X    ,title =    "{Internet Control Message Protocol}"
  714. X    ,year =        "1981"
  715. X    ,month =    "September"
  716. X    ,institution =    "SRI Network Information Center"
  717. X    ,address =    "Menlo Park, California"
  718. X    ,type =        "RFC"
  719. X    ,number =    "792"
  720. X}
  721. X
  722. X@techreport{rfc:ip
  723. X    ,author =    "J. Postel"
  724. X    ,title =    "{Internet Protocol}"
  725. X    ,year =        "1981"
  726. X    ,month =    "September"
  727. X    ,institution =    "SRI Network Information Center"
  728. X    ,address =    "Menlo Park, California"
  729. X    ,type =        "RFC"
  730. X    ,number =    "791"
  731. X}
  732. X
  733. X@incollection{sun:yp
  734. X    ,author =    "{Sun Microsystems}"
  735. X    ,year =        "1988"
  736. X    ,booktitle =    "System \& Network Administration"
  737. X    ,title =    "{The Sun YP Service}"
  738. X    ,month =    "May"
  739. X    ,chapter =    "14"
  740. X    ,pages =    "349--371"
  741. X    ,edition =    "First"
  742. X    ,publisher =    "Sun Microsystems, Inc"
  743. X    ,address =    "Mountain View, California"
  744. X}
  745. X
  746. X@incollection{sun:automount
  747. X    ,author =    "{Sun Microsystems}"
  748. X    ,year =        "1988"
  749. X    ,booktitle =    "SunOS Reference Manual"
  750. X    ,title =    "Automount"
  751. X    ,month =    "May"
  752. X    ,chapter =    "8"
  753. X    ,pages =    "1583--1585"
  754. X    ,edition =    "First"
  755. X    ,publisher =    "Sun Microsystems, Inc"
  756. X    ,address =    "Mountain View, California"
  757. X}
  758. X
  759. X@incollection{sun:rpc
  760. X    ,author =    "{Sun Microsystems}"
  761. X    ,year =        "1988"
  762. X    ,booktitle =    "Network Programming"
  763. X    ,title =    "{Remote Procedure Calls: Protocol Specification}"
  764. X    ,month =    "May"
  765. X    ,chapter =    "6"
  766. X    ,pages =    "143--163"
  767. X    ,edition =    "First"
  768. X    ,publisher =    "Sun Microsystems, Inc"
  769. X    ,address =    "Mountain View, California"
  770. X}
  771. X
  772. X@incollection{sun:nfs
  773. X    ,author =    "{Sun Microsystems}"
  774. X    ,year =        "1988"
  775. X    ,booktitle =    "Network Programming"
  776. X    ,title =    "{Network File System: Version 2 Protocol Specification}"
  777. X    ,month =    "May"
  778. X    ,chapter =    "7"
  779. X    ,pages =    "165--185"
  780. X    ,edition =    "First"
  781. X    ,publisher =    "Sun Microsystems, Inc"
  782. X    ,address =    "Mountain View, California"
  783. X}
  784. END_OF_FILE
  785. if test 3898 -ne `wc -c <'doc/amd.bib'`; then
  786.     echo shar: \"'doc/amd.bib'\" unpacked with wrong size!
  787. fi
  788. # end of 'doc/amd.bib'
  789. fi
  790. if test -f 'doc/nh.doc' -a "${1}" != "-c" ; then 
  791.   echo shar: Will not clobber existing file \"'doc/nh.doc'\"
  792. else
  793. echo shar: Extracting \"'doc/nh.doc'\" \(4900 characters\)
  794. sed "s/^X//" >'doc/nh.doc' <<'END_OF_FILE'
  795. X% Change page size parameters for A4 paper on LaserWriter,
  796. X% allowing for headers and footers. Define some new macros for headers
  797. X% and footers too.
  798. X%
  799. X% MJW 7 Jan 1987
  800. X%
  801. X% USAGE
  802. X%
  803. X% To enable this use \pagestyle{footers}.
  804. X% This also overrides automatically getting chapter titles in headers, but you
  805. X% could restore this by using \leftmark and \rightmark
  806. X% in your own headers and footers.  These macros are set by \chaptermark (and
  807. X% possibly other things too). In one-sided printing all pages are right ones.
  808. X%
  809. X% One-Sided Printing
  810. X%
  811. X% \setheader{your header}
  812. X% \setfooter{your footer}
  813. X% \setchapterhead{header on first page of a chapter}
  814. X% \setchapterfoot{footer on first page of a chapter}
  815. X%
  816. X% Two-sided Printing
  817. X%
  818. X% \setbothheaders{the left one (even no. pages}{the right one (odd)}
  819. X% \setbothfooters{the left one}{the right one}
  820. X% \setchapterhead{header on first page of a chapter}
  821. X% \setchapterfoot{footer on first page of a chapter}
  822. X%
  823. X% Examples
  824. X%
  825. X% To get a page number use \thepage. Use \hfil to get centring etc.
  826. X% Example \setheader{A\hfil\thepage\hfil B}
  827. X% produces A at the extreme left of the page, the number in the middle
  828. X% and B at the extreme right.
  829. X%
  830. X% The following produces chapter title at top left, page number top right,
  831. X% with a line across the page underneath them,
  832. X% Project 1022(1041) bottom left, Task 19.1 bottom right.
  833. X% Except on the first page of a chapter when the heading is empty, and
  834. X% the footer is as before, but with the page number in the middle.
  835. X% \pagestyle{footers}
  836. X% \setheader{\vbox{\hbox to\hsize{\rightmark\hfil\thepage}\vskip 2pt\hrule}}
  837. X% \setfooter{Project 1022(1041)\hfil Task 19.1}
  838. X% \setchapterfoot{Project 1022(1041)\hfil\thepage \hfil Task 19.1}
  839. X
  840. X\oddsidemargin 16pt % MJW actually get 1/2 inch (=32pt) margin because
  841. X                   % of printer offset. was 1pt
  842. X\evensidemargin 16pt % was 1pt
  843. X\marginparwidth 30pt % these gain 53pt width
  844. X\topmargin 5pt      % gains 26pt height (MJW was 16pt)
  845. X\headheight 14pt      % gains 11pt height (MJW was 1pt)
  846. X\headsep 25pt         % gains 24pt height (MJW was 1pt)
  847. X%\footheight 12 pt   % cannot be changed as number must fit
  848. X\footskip 24pt       % gains 6pt height
  849. X\textheight % 528 + 26 + 11 + 24 + 6 + 55 for luck -16 +32 (heads: -10 -15)
  850. X%           650pt
  851. X%            666pt
  852. X        641pt
  853. X\textwidth % 360 + 53 + 47 for luck -15 +8
  854. X           453pt
  855. X%\pagestyle{myheadings}
  856. X%\markboth{LEFT}{RIGHT}
  857. X%left = even, right = odd for two-sided
  858. X% everything is right for one-sided
  859. X\def\evenheadline{}\def\oddheadline{}
  860. X\def\evenfootline{}\def\oddfootline{}
  861. X
  862. X% Use these to set headers and footers for two-sided printing.
  863. X\def\setbothheaders#1#2{\def\evenheadline{#1}\def\oddheadline{#2}}
  864. X\def\setbothfooters#1#2{\def\evenfootline{#1}\def\oddfootline{#2}}
  865. X
  866. X% Use these for one-sided printing.
  867. X\def\setheader#1{\def\oddheadline{#1}}\def\setfooter#1{\def\oddfootline{#1}}
  868. X
  869. X% To set footer on first page of a chapter
  870. X\def\setchapterfoot#1{\def\chapterfoot{#1}}
  871. X\def\setchapterhead#1{\def\chapterhead{#1}}
  872. X
  873. X% Initialise footers to the page number.
  874. X\setbothfooters{\hfil\thepage\hfil}{\hfil\thepage\hfil}
  875. X
  876. X% Initialise chapter footer to page number, header empty.
  877. X\setchapterfoot{\hfil\thepage \hfil}
  878. X\setchapterhead{}
  879. X
  880. X% My version of \chapter
  881. X\def\chapter{\clearpage      % Starts new page.
  882. X%  \if@twoside \cleardoublepage
  883. X%  \else\clearpage\fi      % Starts new page.
  884. X   \thispagestyle{chapterpage}     % Page style of chapter page is 'chapterpage'
  885. X   \global\@topnum\z@        % Prevents figures from going at top of page.
  886. X   \@afterindentfalse        % Suppresses indent in first paragraph.  Change
  887. X   \secdef\@chapter\@schapter}   % to \@afterindenttrue to have indent.
  888. X   
  889. X% Style for first page of a chapter
  890. X\def\ps@chapterpage{\let\@mkboth\markboth
  891. X\def\@evenhead{\chapterhead}\def\@oddhead{\chapterhead}
  892. X\def\@evenfoot{\chapterfoot}\def\@oddfoot{\chapterfoot}}
  893. X
  894. X% Style for headers AND footers.
  895. X\if@twoside         % If two-sided printing.
  896. X\def\ps@footers{\let\@mkboth\markboth
  897. X\def\@evenhead{\evenheadline}\def\@oddhead{\oddheadline}
  898. X\def\@evenfoot{\evenfootline}\def\@oddfoot{\oddfootline}
  899. X% Chapter stuff
  900. X\def\chaptermark##1{\markboth{\uppercase{\ifnum \c@secnumdepth >\m@ne
  901. X \@chapapp\ \thechapter. \ \fi ##1}}{}}
  902. X\def\sectionmark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\z@
  903. X   \thesection. \ \fi ##1}}}
  904. X}
  905. X\else               % If one-sided printing.
  906. X\def\ps@footers{\let\@mkboth\markboth
  907. X\def\@evenhead{\evenheadline}\def\@oddhead{\oddheadline}
  908. X\def\@evenfoot{\evenfootline}\def\@oddfoot{\oddfootline}
  909. X% Chapter stuff
  910. X\def\chaptermark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\m@ne
  911. X \@chapapp\ \thechapter. \ \fi ##1}}}
  912. X}
  913. X\fi
  914. X
  915. X% Debugging stuff.
  916. X%\let\markbothorig\markboth
  917. X%\def\markboth#1#2{\typeout{---Markboth: \#1=#1, \#2=#2\newline}
  918. X%  \markbothorig {#1} {#2}}
  919. X%  
  920. X%\let\markrightorig\markright
  921. X%\def\markright#1{\typeout{---Markright: \#1=#1\newline}
  922. X%  \markrightorig {#1}}
  923. END_OF_FILE
  924. if test 4900 -ne `wc -c <'doc/nh.doc'`; then
  925.     echo shar: \"'doc/nh.doc'\" unpacked with wrong size!
  926. fi
  927. # end of 'doc/nh.doc'
  928. fi
  929. if test -f 'info_file.c' -a "${1}" != "-c" ; then 
  930.   echo shar: Will not clobber existing file \"'info_file.c'\"
  931. else
  932. echo shar: Extracting \"'info_file.c'\" \(4399 characters\)
  933. sed "s/^X//" >'info_file.c' <<'END_OF_FILE'
  934. X/*
  935. X * $Id: info_file.c,v 5.1.1.1 90/01/11 17:07:25 jsp Exp Locker: jsp $
  936. X *
  937. X * Copyright (c) 1990 Jan-Simon Pendry
  938. X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  939. X * Copyright (c) 1990 The Regents of the University of California.
  940. X * All rights reserved.
  941. X *
  942. X * This code is derived from software contributed to Berkeley by
  943. X * Jan-Simon Pendry at Imperial College, London.
  944. X *
  945. X * Redistribution and use in source and binary forms are permitted
  946. X * provided that the above copyright notice and this paragraph are
  947. X * duplicated in all such forms and that any documentation,
  948. X * advertising materials, and other materials related to such
  949. X * distribution and use acknowledge that the software was developed
  950. X * by Imperial College of Science, Technology and Medicine, London, UK.
  951. X * The names of the College and University may not be used to endorse
  952. X * or promote products derived from this software without specific
  953. X * prior written permission.
  954. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  955. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  956. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  957. X *
  958. X *    %W% (Berkeley) %G%
  959. X */
  960. X
  961. X/*
  962. X * Get info from file
  963. X */
  964. X
  965. X#include "am.h"
  966. X
  967. X#ifdef HAS_FILE_MAPS
  968. X#include <ctype.h>
  969. X#include <sys/stat.h>
  970. X
  971. X#define    MAX_LINE_LEN    2048
  972. X
  973. Xstatic int read_line(buf, size, fp)
  974. Xchar *buf;
  975. Xint size;
  976. XFILE *fp;
  977. X{
  978. X    int done = 0;
  979. X
  980. X    do {
  981. X        while (fgets(buf, size, fp)) {
  982. X            int len = strlen(buf);
  983. X            done += len;
  984. X            if (len > 1 && buf[len-2] == '\\' &&
  985. X                    buf[len-1] == '\n') {
  986. X                int ch;
  987. X                buf += len - 2;
  988. X                size -= len - 2;
  989. X                /*
  990. X                 * Skip leading white space on next line
  991. X                 */
  992. X                while ((ch = getc(fp)) != EOF &&
  993. X                    isascii(ch) && isspace(ch))
  994. X                        ;
  995. X                (void) ungetc(ch, fp);
  996. X            } else {
  997. X                return done;
  998. X            }
  999. X        }
  1000. X    } while (size > 0 && !feof(fp));
  1001. X
  1002. X    return done;
  1003. X}
  1004. X
  1005. X/*
  1006. X * Try to locate a key in a file
  1007. X */
  1008. Xstatic int search_or_reload_file(fp, map, key, val, m, fn)
  1009. XFILE *fp;
  1010. Xchar *map;
  1011. Xchar *key;
  1012. Xchar **val;
  1013. Xmnt_map *m;
  1014. Xvoid (*fn) P((mnt_map*, char*, char*));
  1015. X{
  1016. X    char key_val[MAX_LINE_LEN];
  1017. X    int chuck = 0;
  1018. X    int line_no = 0;
  1019. X
  1020. X    while (read_line(key_val, sizeof(key_val), fp)) {
  1021. X        char *kp;
  1022. X        char *cp;
  1023. X        char *hash;
  1024. X        int len = strlen(key_val);
  1025. X        line_no++;
  1026. X
  1027. X        /*
  1028. X         * Make sure we got the whole line
  1029. X         */
  1030. X        if (key_val[len-1] != '\n') {
  1031. X            plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map);
  1032. X            chuck = 1;
  1033. X        } else {
  1034. X            key_val[len-1] = '\0';
  1035. X        }
  1036. X
  1037. X        /*
  1038. X         * Strip comments
  1039. X         */
  1040. X        hash = strchr(key_val, '#');
  1041. X        if (hash)
  1042. X            *hash = '\0';
  1043. X
  1044. X        /*
  1045. X         * Find start of key
  1046. X         */
  1047. X        for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++)
  1048. X            ;
  1049. X
  1050. X        /*
  1051. X         * Ignore blank lines
  1052. X         */
  1053. X        if (!*kp)
  1054. X            goto again;
  1055. X
  1056. X        /*
  1057. X         * Find end of key
  1058. X         */
  1059. X        for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++)
  1060. X            ;
  1061. X
  1062. X        /*
  1063. X         * Check whether key matches
  1064. X         */
  1065. X        if (*cp)
  1066. X            *cp++ = '\0';
  1067. X
  1068. X        if ((*key == *kp && strcmp(key, kp) == 0) || fn) {
  1069. X            while (*cp && isascii(*cp) && isspace(*cp))
  1070. X                cp++;
  1071. X            if (*cp) {
  1072. X                /*
  1073. X                 * Return a copy of the data
  1074. X                 */
  1075. X                char *dc = strdup(cp);
  1076. X                if (fn)
  1077. X                    (*fn)(m, kp, dc);
  1078. X                else
  1079. X                    *val = dc;
  1080. X#ifdef DEBUG
  1081. X                dlog("%s returns %s", key, dc);
  1082. X#endif
  1083. X                if (!fn)
  1084. X                    return 0;
  1085. X            } else {
  1086. X                plog(XLOG_USER, "%s: line %d has no value field", map, line_no);
  1087. X            }
  1088. X        }
  1089. X
  1090. Xagain:
  1091. X        /*
  1092. X         * If the last read didn't get a whole line then
  1093. X         * throw away the remainder before continuing...
  1094. X         */
  1095. X        if (chuck) {
  1096. X            while (fgets(key_val, sizeof(key_val), fp) &&
  1097. X                !strchr(key_val, '\n'))
  1098. X                    ;
  1099. X            chuck = 0;
  1100. X        }
  1101. X    }
  1102. X
  1103. X    return fn ? 0 : ENOENT;
  1104. X}
  1105. X
  1106. Xint file_init(map)
  1107. Xchar *map;
  1108. X{
  1109. X    FILE *mapf = fopen(map, "r");
  1110. X    if (mapf) {
  1111. X        (void) fclose(mapf);
  1112. X        return 0;
  1113. X    }
  1114. X    return errno;
  1115. X}
  1116. X
  1117. Xint file_reload(m, map, fn)
  1118. Xmnt_map *m;
  1119. Xchar *map;
  1120. Xvoid (*fn)();
  1121. X{
  1122. X    FILE *mapf = fopen(map, "r");
  1123. X    if (mapf) {
  1124. X        int error = search_or_reload_file(mapf, map, 0, 0, m, fn);
  1125. X        (void) fclose(mapf);
  1126. X        return error;
  1127. X    }
  1128. X
  1129. X    return errno;
  1130. X}
  1131. X
  1132. Xint file_search(m, map, key, pval, tp)
  1133. Xmnt_map *m;
  1134. Xchar *map;
  1135. Xchar *key;
  1136. Xchar **pval;
  1137. Xtime_t *tp;
  1138. X{
  1139. X    FILE *mapf = fopen(map, "r");
  1140. X    if (mapf) {
  1141. X        struct stat stb;
  1142. X        int error;
  1143. X        error = fstat(fileno(mapf), &stb);
  1144. X        if (!error && *tp < stb.st_mtime) {
  1145. X            *tp = stb.st_mtime;
  1146. X            error = -1;
  1147. X        } else {
  1148. X            error = search_or_reload_file(mapf, map, key, pval, 0, 0);
  1149. X        }
  1150. X        (void) fclose(mapf);
  1151. X        return error;
  1152. X    }
  1153. X
  1154. X    return errno;
  1155. X}
  1156. X#endif
  1157. END_OF_FILE
  1158. if test 4399 -ne `wc -c <'info_file.c'`; then
  1159.     echo shar: \"'info_file.c'\" unpacked with wrong size!
  1160. fi
  1161. # end of 'info_file.c'
  1162. fi
  1163. if test -f 'mount_fs.c' -a "${1}" != "-c" ; then 
  1164.   echo shar: Will not clobber existing file \"'mount_fs.c'\"
  1165. else
  1166. echo shar: Extracting \"'mount_fs.c'\" \(5414 characters\)
  1167. sed "s/^X//" >'mount_fs.c' <<'END_OF_FILE'
  1168. X/*
  1169. X * $Id: mount_fs.c,v 5.1.1.2 90/01/11 17:10:47 jsp Exp Locker: jsp $
  1170. X *
  1171. X * Copyright (c) 1990 Jan-Simon Pendry
  1172. X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  1173. X * Copyright (c) 1990 The Regents of the University of California.
  1174. X * All rights reserved.
  1175. X *
  1176. X * This code is derived from software contributed to Berkeley by
  1177. X * Jan-Simon Pendry at Imperial College, London.
  1178. X *
  1179. X * Redistribution and use in source and binary forms are permitted
  1180. X * provided that the above copyright notice and this paragraph are
  1181. X * duplicated in all such forms and that any documentation,
  1182. X * advertising materials, and other materials related to such
  1183. X * distribution and use acknowledge that the software was developed
  1184. X * by Imperial College of Science, Technology and Medicine, London, UK.
  1185. X * The names of the College and University may not be used to endorse
  1186. X * or promote products derived from this software without specific
  1187. X * prior written permission.
  1188. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1189. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1190. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1191. X *
  1192. X *    %W% (Berkeley) %G%
  1193. X */
  1194. X
  1195. X#include "am.h"
  1196. X#ifdef NFS_3
  1197. Xtypedef nfs_fh fhandle_t;
  1198. X#endif
  1199. X#include <sys/mount.h>
  1200. X
  1201. X/*
  1202. X * System Vr4 / SunOS 4.1 compatibility
  1203. X * - put dev= in the options list
  1204. X *
  1205. X * From: Brent Callaghan <brent@eng.sun.com>
  1206. X */
  1207. X#define    MNTINFO_DEV    "dev"
  1208. X#include <sys/stat.h>
  1209. X
  1210. Xint compute_mount_flags(mnt)
  1211. Xstruct mntent *mnt;
  1212. X{
  1213. X    int flags;
  1214. X#ifdef NFS_4
  1215. X    flags = M_NEWTYPE;
  1216. X#else
  1217. X    flags = 0;
  1218. X#endif
  1219. X
  1220. X    /*
  1221. X     * Crack basic mount options
  1222. X     */
  1223. X    flags |= hasmntopt(mnt, "ro") ? M_RDONLY : 0;
  1224. X#ifdef M_CACHE
  1225. X    flags |= hasmntopt(mnt, "nocache") ? M_NOCACHE : 0;
  1226. X#endif
  1227. X#ifdef M_GRPID
  1228. X    flags |= hasmntopt(mnt, "grpid") ? M_GRPID : 0;
  1229. X#endif
  1230. X#ifdef M_MULTI
  1231. X    flags |= hasmntopt(mnt, "multi") ? M_MULTI : 0;
  1232. X#endif
  1233. X#ifdef M_NODEV
  1234. X    flags |= hasmntopt(mnt, "nodev") ? M_NODEV : 0;
  1235. X#endif
  1236. X#ifdef M_NOEXEC
  1237. X    flags |= hasmntopt(mnt, "noexec") ? M_NOEXEC : 0;
  1238. X#endif
  1239. X#ifdef M_NOSUB
  1240. X    flags |= hasmntopt(mnt, "nosub") ? M_NOSUB : 0;
  1241. X#endif
  1242. X#ifdef hpux
  1243. X/* HP-UX has an annoying feature of printing error msgs on /dev/console */
  1244. X#undef M_NOSUID
  1245. X#endif
  1246. X#ifdef M_NOSUID
  1247. X    flags |= hasmntopt(mnt, "nosuid") ? M_NOSUID : 0;
  1248. X#endif
  1249. X#ifdef M_SYNC
  1250. X    flags |= hasmntopt(mnt, "sync") ? M_SYNC : 0;
  1251. X#endif
  1252. X
  1253. X    return flags;
  1254. X}
  1255. X
  1256. Xint mount_fs(mnt, flags, mnt_data, retry, type)
  1257. Xstruct mntent *mnt;
  1258. Xint flags;
  1259. Xcaddr_t mnt_data;
  1260. Xint retry;
  1261. XMTYPE_TYPE type;
  1262. X{
  1263. X    int error = 0;
  1264. X    int automount = 0;
  1265. X#ifdef MNTINFO_DEV
  1266. X    struct stat stb;
  1267. X    char *xopts = 0;
  1268. X#endif
  1269. X
  1270. X#ifdef DEBUG
  1271. X#ifdef NFS_4
  1272. X    dlog("%s fstype %s (%s) flags %#x (%s)",
  1273. X        mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
  1274. X#else
  1275. X    dlog("%s fstype %d (%s) flags %#x (%s)",
  1276. X        mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
  1277. X#endif /* NFS_4 */
  1278. X#endif /* DEBUG */
  1279. X
  1280. X    /*
  1281. X     * Fake some mount table entries for the automounter
  1282. X     */
  1283. X    if (STREQ(mnt->mnt_type, MNTTYPE_AUTO)) {
  1284. X        automount = 1;
  1285. X        mnt->mnt_fsname = pid_fsname;
  1286. X        /*
  1287. X         * Try it with the normal name
  1288. X         */
  1289. X#ifdef notdef
  1290. X        mnt->mnt_type = MNTTYPE_IGNORE;
  1291. X#endif
  1292. X        mnt->mnt_type = MNTTYPE_NFS;
  1293. X        /*
  1294. X         * Background the mount, so that the stat of the
  1295. X         * mountpoint is done in a background process.
  1296. X         */
  1297. X        if (background())
  1298. X            return 0;
  1299. X    }
  1300. X
  1301. Xagain:
  1302. X    clock_valid = 0;
  1303. X    error = MOUNT_TRAP(type, mnt, flags, mnt_data);
  1304. X    if (error < 0)
  1305. X        plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir);
  1306. X    if (error < 0 && --retry > 0) {
  1307. X        sleep(1);
  1308. X        goto again;
  1309. X    }
  1310. X    if (error < 0) {
  1311. X        if (automount)
  1312. X            going_down(errno);
  1313. X        return errno;
  1314. X    }
  1315. X
  1316. X#ifdef UPDATE_MTAB
  1317. X#ifdef MNTINFO_DEV
  1318. X    /*
  1319. X     * Add the extra dev= field to the mount table.
  1320. X     */
  1321. X    if (stat(mnt->mnt_dir, &stb) == 0) {
  1322. X        char *zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 32);
  1323. X        xopts = mnt->mnt_opts;
  1324. X        if (sizeof(stb.st_dev) == 2) {
  1325. X            /* SunOS 4.1 */
  1326. X            sprintf(zopts, "%s,%s=%04lx", xopts, MNTINFO_DEV,
  1327. X                    (u_long) stb.st_dev & 0xffff);
  1328. X        } else {
  1329. X            /* System Vr4 */
  1330. X            sprintf(zopts, "%s,%s=%08lx", xopts, MNTINFO_DEV,
  1331. X                    (u_long) stb.st_dev);
  1332. X        }
  1333. X        mnt->mnt_opts = zopts;
  1334. X    }
  1335. X#endif /* MNTINFO_DEV */
  1336. X
  1337. X#ifdef hpux
  1338. X    /*
  1339. X     * Yet another gratuitously incompatible change in HP-UX
  1340. X     */
  1341. X    mnt->mnt_time = clocktime();
  1342. X#endif
  1343. X    write_mntent(mnt);
  1344. X#ifdef MNTINFO_DEV
  1345. X    if (xopts) {
  1346. X        free(mnt->mnt_opts);
  1347. X        mnt->mnt_opts = xopts;
  1348. X    }
  1349. X#endif
  1350. X#endif /* UPDATE_MTAB */
  1351. X
  1352. X    /*
  1353. X     * Needed this way since mnt may contain a pointer
  1354. X     * to a local variable in this stack frame.
  1355. X     */
  1356. X    if (automount)
  1357. X        going_down(0);
  1358. X    return 0;
  1359. X}
  1360. X
  1361. X#ifdef NEED_MNTOPT_PARSER
  1362. X/*
  1363. X * Some systems don't provide these to the user,
  1364. X * but amd needs them, so...
  1365. X *
  1366. X * From: Piete Brooks <pb@cl.cam.ac.uk>
  1367. X */
  1368. X
  1369. X#include <ctype.h>
  1370. X
  1371. Xstatic char *nextmntopt(p)
  1372. Xchar **p;
  1373. X{
  1374. X    char *cp = *p;
  1375. X    char *rp;
  1376. X    /*
  1377. X     * Skip past white space
  1378. X     */
  1379. X    while (*cp && isspace(*cp))
  1380. X        cp++;
  1381. X    /*
  1382. X     * Word starts here
  1383. X     */
  1384. X    rp = cp;
  1385. X    /*
  1386. X     * Scan to send of string or separator
  1387. X     */
  1388. X    while (*cp && *cp != ',')
  1389. X        cp++;
  1390. X    /*
  1391. X     * If separator found the overwrite with nul char.
  1392. X     */
  1393. X    if (*cp) {
  1394. X        *cp = '\0';
  1395. X        cp++;
  1396. X    }
  1397. X    /*
  1398. X     * Return value for next call
  1399. X     */
  1400. X    *p = cp;
  1401. X    return rp;
  1402. X}
  1403. X
  1404. Xchar *hasmntopt(mnt, opt)
  1405. Xstruct mntent *mnt;
  1406. Xchar *opt;
  1407. X{
  1408. X    char t[MNTMAXSTR];
  1409. X    char *f;
  1410. X    char *o = t;
  1411. X    int l = strlen(opt);
  1412. X    strcpy(t, mnt->mnt_opts);
  1413. X
  1414. X    while (*(f = nextmntopt(&o)))
  1415. X        if (strncmp(opt, f, l) == 0)
  1416. X            return f - t + mnt->mnt_opts;
  1417. X
  1418. X    return 0;
  1419. X}
  1420. X#endif /* NEED_MNTOPT_PARSER */
  1421. END_OF_FILE
  1422. if test 5414 -ne `wc -c <'mount_fs.c'`; then
  1423.     echo shar: \"'mount_fs.c'\" unpacked with wrong size!
  1424. fi
  1425. # end of 'mount_fs.c'
  1426. fi
  1427. if test -f 'nfs_prot_svc.c' -a "${1}" != "-c" ; then 
  1428.   echo shar: Will not clobber existing file \"'nfs_prot_svc.c'\"
  1429. else
  1430. echo shar: Extracting \"'nfs_prot_svc.c'\" \(4786 characters\)
  1431. sed "s/^X//" >'nfs_prot_svc.c' <<'END_OF_FILE'
  1432. X/*
  1433. X * $Id: nfs_prot_svc.c,v 5.1 89/11/17 18:21:23 jsp Exp Locker: jsp $
  1434. X *
  1435. X * Copyright (c) 1989 Jan-Simon Pendry
  1436. X * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  1437. X * Copyright (c) 1989 The Regents of the University of California.
  1438. X * All rights reserved.
  1439. X *
  1440. X * This code is derived from software contributed to Berkeley by
  1441. X * Jan-Simon Pendry at Imperial College, London.
  1442. X *
  1443. X * Redistribution and use in source and binary forms are permitted
  1444. X * provided that the above copyright notice and this paragraph are
  1445. X * duplicated in all such forms and that any documentation,
  1446. X * advertising materials, and other materials related to such
  1447. X * distribution and use acknowledge that the software was developed
  1448. X * by Imperial College of Science, Technology and Medicine, London, UK.
  1449. X * The names of the College and University may not be used to endorse
  1450. X * or promote products derived from this software without specific
  1451. X * prior written permission.
  1452. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1453. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1454. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1455. X *
  1456. X *    %W% (Berkeley) %G%
  1457. X */
  1458. X
  1459. X#include "am.h"
  1460. X
  1461. Xvoid nfs_program_2(rqstp, transp)
  1462. Xstruct svc_req *rqstp;
  1463. XSVCXPRT *transp;
  1464. X{
  1465. X    union {
  1466. X        nfs_fh nfsproc_getattr_2_arg;
  1467. X        sattrargs nfsproc_setattr_2_arg;
  1468. X        diropargs nfsproc_lookup_2_arg;
  1469. X        nfs_fh nfsproc_readlink_2_arg;
  1470. X        readargs nfsproc_read_2_arg;
  1471. X        writeargs nfsproc_write_2_arg;
  1472. X        createargs nfsproc_create_2_arg;
  1473. X        diropargs nfsproc_remove_2_arg;
  1474. X        renameargs nfsproc_rename_2_arg;
  1475. X        linkargs nfsproc_link_2_arg;
  1476. X        symlinkargs nfsproc_symlink_2_arg;
  1477. X        createargs nfsproc_mkdir_2_arg;
  1478. X        diropargs nfsproc_rmdir_2_arg;
  1479. X        readdirargs nfsproc_readdir_2_arg;
  1480. X        nfs_fh nfsproc_statfs_2_arg;
  1481. X    } argument;
  1482. X    char *result;
  1483. X    bool_t (*xdr_argument)(), (*xdr_result)();
  1484. X    char *(*local)();
  1485. X
  1486. X    switch (rqstp->rq_proc) {
  1487. X    case NFSPROC_NULL:
  1488. X        xdr_argument = xdr_void;
  1489. X        xdr_result = xdr_void;
  1490. X        local = (char *(*)()) nfsproc_null_2;
  1491. X        break;
  1492. X
  1493. X    case NFSPROC_GETATTR:
  1494. X        xdr_argument = xdr_nfs_fh;
  1495. X        xdr_result = xdr_attrstat;
  1496. X        local = (char *(*)()) nfsproc_getattr_2;
  1497. X        break;
  1498. X
  1499. X    case NFSPROC_SETATTR:
  1500. X        xdr_argument = xdr_sattrargs;
  1501. X        xdr_result = xdr_attrstat;
  1502. X        local = (char *(*)()) nfsproc_setattr_2;
  1503. X        break;
  1504. X
  1505. X    case NFSPROC_ROOT:
  1506. X        xdr_argument = xdr_void;
  1507. X        xdr_result = xdr_void;
  1508. X        local = (char *(*)()) nfsproc_root_2;
  1509. X        break;
  1510. X
  1511. X    case NFSPROC_LOOKUP:
  1512. X        xdr_argument = xdr_diropargs;
  1513. X        xdr_result = xdr_diropres;
  1514. X        local = (char *(*)()) nfsproc_lookup_2;
  1515. X        break;
  1516. X
  1517. X    case NFSPROC_READLINK:
  1518. X        xdr_argument = xdr_nfs_fh;
  1519. X        xdr_result = xdr_readlinkres;
  1520. X        local = (char *(*)()) nfsproc_readlink_2;
  1521. X        break;
  1522. X
  1523. X    case NFSPROC_READ:
  1524. X        xdr_argument = xdr_readargs;
  1525. X        xdr_result = xdr_readres;
  1526. X        local = (char *(*)()) nfsproc_read_2;
  1527. X        break;
  1528. X
  1529. X    case NFSPROC_WRITECACHE:
  1530. X        xdr_argument = xdr_void;
  1531. X        xdr_result = xdr_void;
  1532. X        local = (char *(*)()) nfsproc_writecache_2;
  1533. X        break;
  1534. X
  1535. X    case NFSPROC_WRITE:
  1536. X        xdr_argument = xdr_writeargs;
  1537. X        xdr_result = xdr_attrstat;
  1538. X        local = (char *(*)()) nfsproc_write_2;
  1539. X        break;
  1540. X
  1541. X    case NFSPROC_CREATE:
  1542. X        xdr_argument = xdr_createargs;
  1543. X        xdr_result = xdr_diropres;
  1544. X        local = (char *(*)()) nfsproc_create_2;
  1545. X        break;
  1546. X
  1547. X    case NFSPROC_REMOVE:
  1548. X        xdr_argument = xdr_diropargs;
  1549. X        xdr_result = xdr_nfsstat;
  1550. X        local = (char *(*)()) nfsproc_remove_2;
  1551. X        break;
  1552. X
  1553. X    case NFSPROC_RENAME:
  1554. X        xdr_argument = xdr_renameargs;
  1555. X        xdr_result = xdr_nfsstat;
  1556. X        local = (char *(*)()) nfsproc_rename_2;
  1557. X        break;
  1558. X
  1559. X    case NFSPROC_LINK:
  1560. X        xdr_argument = xdr_linkargs;
  1561. X        xdr_result = xdr_nfsstat;
  1562. X        local = (char *(*)()) nfsproc_link_2;
  1563. X        break;
  1564. X
  1565. X    case NFSPROC_SYMLINK:
  1566. X        xdr_argument = xdr_symlinkargs;
  1567. X        xdr_result = xdr_nfsstat;
  1568. X        local = (char *(*)()) nfsproc_symlink_2;
  1569. X        break;
  1570. X
  1571. X    case NFSPROC_MKDIR:
  1572. X        xdr_argument = xdr_createargs;
  1573. X        xdr_result = xdr_diropres;
  1574. X        local = (char *(*)()) nfsproc_mkdir_2;
  1575. X        break;
  1576. X
  1577. X    case NFSPROC_RMDIR:
  1578. X        xdr_argument = xdr_diropargs;
  1579. X        xdr_result = xdr_nfsstat;
  1580. X        local = (char *(*)()) nfsproc_rmdir_2;
  1581. X        break;
  1582. X
  1583. X    case NFSPROC_READDIR:
  1584. X        xdr_argument = xdr_readdirargs;
  1585. X        xdr_result = xdr_readdirres;
  1586. X        local = (char *(*)()) nfsproc_readdir_2;
  1587. X        break;
  1588. X
  1589. X    case NFSPROC_STATFS:
  1590. X        xdr_argument = xdr_nfs_fh;
  1591. X        xdr_result = xdr_statfsres;
  1592. X        local = (char *(*)()) nfsproc_statfs_2;
  1593. X        break;
  1594. X
  1595. X    default:
  1596. X        svcerr_noproc(transp);
  1597. X        return;
  1598. X    }
  1599. X    bzero((char *)&argument, sizeof(argument));
  1600. X    if (!svc_getargs(transp, xdr_argument, &argument)) {
  1601. X        svcerr_decode(transp);
  1602. X        return;
  1603. X    }
  1604. X    result = (*local)(&argument, rqstp);
  1605. X    if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
  1606. X        svcerr_systemerr(transp);
  1607. X    }
  1608. X    if (!svc_freeargs(transp, xdr_argument, &argument)) {
  1609. X        plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_1");
  1610. X        going_down(1);
  1611. X    }
  1612. X}
  1613. X
  1614. END_OF_FILE
  1615. if test 4786 -ne `wc -c <'nfs_prot_svc.c'`; then
  1616.     echo shar: \"'nfs_prot_svc.c'\" unpacked with wrong size!
  1617. fi
  1618. # end of 'nfs_prot_svc.c'
  1619. fi
  1620. if test -f 'restart.c' -a "${1}" != "-c" ; then 
  1621.   echo shar: Will not clobber existing file \"'restart.c'\"
  1622. else
  1623. echo shar: Extracting \"'restart.c'\" \(4527 characters\)
  1624. sed "s/^X//" >'restart.c' <<'END_OF_FILE'
  1625. X/*
  1626. X * $Id: restart.c,v 5.1.1.2 90/01/11 17:18:41 jsp Exp Locker: jsp $
  1627. X *
  1628. X * Copyright (c) 1990 Jan-Simon Pendry
  1629. X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  1630. X * Copyright (c) 1990 The Regents of the University of California.
  1631. X * All rights reserved.
  1632. X *
  1633. X * This code is derived from software contributed to Berkeley by
  1634. X * Jan-Simon Pendry at Imperial College, London.
  1635. X *
  1636. X * Redistribution and use in source and binary forms are permitted
  1637. X * provided that the above copyright notice and this paragraph are
  1638. X * duplicated in all such forms and that any documentation,
  1639. X * advertising materials, and other materials related to such
  1640. X * distribution and use acknowledge that the software was developed
  1641. X * by Imperial College of Science, Technology and Medicine, London, UK.
  1642. X * The names of the College and University may not be used to endorse
  1643. X * or promote products derived from this software without specific
  1644. X * prior written permission.
  1645. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1646. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1647. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1648. X *
  1649. X *    %W% (Berkeley) %G%
  1650. X */
  1651. X
  1652. X#include "am.h"
  1653. X
  1654. X/*
  1655. X * Handle an amd restart.
  1656. X *
  1657. X * Scan through the mount list finding all "interesting" mount points.
  1658. X * Next hack up partial data structures and add the mounted file
  1659. X * system to the list of known filesystems.  This will leave a
  1660. X * dangling reference to that filesystems, so when the filesystem is
  1661. X * finally inherited, an extra "free" must be done on it.
  1662. X *
  1663. X * This module relies on internal details of other components.  If
  1664. X * you change something else make *sure* restart() still works.
  1665. X */
  1666. Xvoid restart()
  1667. X{
  1668. X    /*
  1669. X     * Read the existing mount table
  1670. X     */
  1671. X    mntlist *ml, *mlp;
  1672. X
  1673. X    /*
  1674. X     * For each entry, find nfs, ufs or auto mounts
  1675. X     * and create a partial am_node to represent it.
  1676. X     */
  1677. X    for (mlp = ml = read_mtab("restart"); mlp; mlp = mlp->mnext) {
  1678. X        struct mntent *me = mlp->mnt;
  1679. X        am_ops *fs_ops = 0;
  1680. X        if (STREQ(me->mnt_type, MTAB_TYPE_UFS)) {
  1681. X            /*
  1682. X             * UFS entry
  1683. X             */
  1684. X            fs_ops = &ufs_ops;
  1685. X        } else if (STREQ(me->mnt_type, MTAB_TYPE_NFS)) {
  1686. X            /*
  1687. X             * NFS entry, or possibly an Amd entry...
  1688. X             */
  1689. X            int au_pid;
  1690. X            char *colon = strchr(me->mnt_fsname, ':');
  1691. X            if (colon && sscanf(colon, ":(pid%d)", &au_pid) == 1) {
  1692. X                plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir);
  1693. X                fs_ops = &sfs_ops;
  1694. X            } else {
  1695. X                fs_ops = &nfs_ops;
  1696. X            }
  1697. X#ifdef MTAB_TYPE_MFS
  1698. X        } else if (STREQ(me->mnt_type, MTAB_TYPE_MFS)) {
  1699. X            /*
  1700. X             * MFS entry.  Fake with a symlink.
  1701. X             */
  1702. X            fs_ops = &sfs_ops;
  1703. X#endif
  1704. X        } else {
  1705. X            /*
  1706. X             * Catch everything else with symlinks to
  1707. X             * avoid recursive mounts.  This is debatable...
  1708. X             */
  1709. X            fs_ops = &sfs_ops;
  1710. X        }
  1711. X
  1712. X        /*
  1713. X         * If we found something to do
  1714. X         */
  1715. X        if (fs_ops) {
  1716. X            mntfs *mf;
  1717. X            am_opts mo;
  1718. X            char *cp;
  1719. X            cp = strchr(me->mnt_fsname, ':');
  1720. X            /*
  1721. X             * Partially fake up an opts structure
  1722. X             */
  1723. X            mo.opt_rhost = 0;
  1724. X            mo.opt_rfs = 0;
  1725. X            if (cp) {
  1726. X                *cp = '\0';
  1727. X                mo.opt_rhost = strdup(me->mnt_fsname);
  1728. X                mo.opt_rfs = strdup(cp+1);
  1729. X                *cp = ':';
  1730. X            } else if (fs_ops->ffserver == find_nfs_srvr) {
  1731. X                /* 
  1732. X                 * Prototype 4.4 BSD used to end up here -
  1733. X                 * might as well keep the workaround for now
  1734. X                 */
  1735. X                plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname);
  1736. X                mo.opt_rhost = strdup(me->mnt_fsname);
  1737. X                mo.opt_rfs = strdup("/");
  1738. X                me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/");
  1739. X            }
  1740. X            mo.opt_fs = me->mnt_dir;
  1741. X
  1742. X            /*
  1743. X             * Make a new mounted filesystem
  1744. X             */
  1745. X            mf = find_mntfs(fs_ops, &mo, me->mnt_dir,
  1746. X                me->mnt_fsname, me->mnt_opts);
  1747. X            if (mf->mf_refc == 1) {
  1748. X                mf->mf_flags |= MFF_RESTART|MFF_MOUNTED;
  1749. X                mf->mf_error = 0;    /* Already mounted correctly */
  1750. X                /*
  1751. X                 * If the restarted type is a link then
  1752. X                 * don't time out.
  1753. X                 */
  1754. X                if (fs_ops == &sfs_ops)
  1755. X                    mf->mf_flags |= MFF_RSTKEEP;
  1756. X                if (fs_ops->fs_init) {
  1757. X                    /*
  1758. X                     * Don't care whether this worked since
  1759. X                     * it is checked again when the fs is
  1760. X                     * inherited.
  1761. X                     */
  1762. X                    (void) (*fs_ops->fs_init)(mf);
  1763. X                }
  1764. X
  1765. X                plog(XLOG_INFO, "%s restarted fstype %s on %s",
  1766. X                    me->mnt_fsname, fs_ops->fs_type, me->mnt_dir);
  1767. X            } else {
  1768. X                /* Something strange happened - two mounts at the same place! */
  1769. X                free_mntfs(mf);
  1770. X            }
  1771. X            /*
  1772. X             * Clean up mo
  1773. X             */
  1774. X            if (mo.opt_rhost)
  1775. X                free(mo.opt_rhost);
  1776. X            if (mo.opt_rfs)
  1777. X                free(mo.opt_rfs);
  1778. X        }
  1779. X    }
  1780. X
  1781. X    /*
  1782. X     * Free the mount list
  1783. X     */
  1784. X    free_mntlist(ml);
  1785. X}
  1786. END_OF_FILE
  1787. if test 4527 -ne `wc -c <'restart.c'`; then
  1788.     echo shar: \"'restart.c'\" unpacked with wrong size!
  1789. fi
  1790. # end of 'restart.c'
  1791. fi
  1792. if test -f 'sched.c' -a "${1}" != "-c" ; then 
  1793.   echo shar: Will not clobber existing file \"'sched.c'\"
  1794. else
  1795. echo shar: Extracting \"'sched.c'\" \(4945 characters\)
  1796. sed "s/^X//" >'sched.c' <<'END_OF_FILE'
  1797. X/*
  1798. X * $Id: sched.c,v 5.1.1.1 90/01/11 17:19:12 jsp Exp Locker: jsp $
  1799. X *
  1800. X * Copyright (c) 1990 Jan-Simon Pendry
  1801. X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  1802. X * Copyright (c) 1990 The Regents of the University of California.
  1803. X * All rights reserved.
  1804. X *
  1805. X * This code is derived from software contributed to Berkeley by
  1806. X * Jan-Simon Pendry at Imperial College, London.
  1807. X *
  1808. X * Redistribution and use in source and binary forms are permitted
  1809. X * provided that the above copyright notice and this paragraph are
  1810. X * duplicated in all such forms and that any documentation,
  1811. X * advertising materials, and other materials related to such
  1812. X * distribution and use acknowledge that the software was developed
  1813. X * by Imperial College of Science, Technology and Medicine, London, UK.
  1814. X * The names of the College and University may not be used to endorse
  1815. X * or promote products derived from this software without specific
  1816. X * prior written permission.
  1817. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1818. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1819. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1820. X *
  1821. X *    %W% (Berkeley) %G%
  1822. X */
  1823. X
  1824. X/*
  1825. X * Process scheduler
  1826. X */
  1827. X
  1828. X#include "am.h"
  1829. X#include <sys/signal.h>
  1830. X#include WAIT
  1831. X#include <setjmp.h>
  1832. Xextern jmp_buf select_intr;
  1833. Xextern int select_intr_valid;
  1834. X
  1835. Xtypedef struct pjob pjob;
  1836. Xstruct pjob {
  1837. X    qelem hdr;            /* Linked list */
  1838. X    int pid;            /* Process ID of job */
  1839. X    cb_fun cb_fun;            /* Callback function */
  1840. X    voidp cb_closure;        /* Closure for callback */
  1841. X    union wait w;            /* Status filled in by sigchld */
  1842. X    voidp wchan;            /* Wait channel */
  1843. X};
  1844. X
  1845. Xextern qelem proc_list_head;
  1846. Xqelem proc_list_head = { &proc_list_head, &proc_list_head };
  1847. Xextern qelem proc_wait_list;
  1848. Xqelem proc_wait_list = { &proc_wait_list, &proc_wait_list };
  1849. X
  1850. Xint task_notify_todo;
  1851. X
  1852. Xvoid ins_que(elem, pred)
  1853. Xqelem *elem, *pred;
  1854. X{
  1855. X    qelem *p = pred->q_forw;
  1856. X    elem->q_back = pred;
  1857. X    elem->q_forw = p;
  1858. X    pred->q_forw = elem;
  1859. X    p->q_back = elem;
  1860. X}
  1861. X
  1862. Xvoid rem_que(elem)
  1863. Xqelem *elem;
  1864. X{
  1865. X    qelem *p = elem->q_forw;
  1866. X    qelem *p2 = elem->q_back;
  1867. X    p2->q_forw = p;
  1868. X    p->q_back = p2;
  1869. X}
  1870. X
  1871. Xstatic pjob *sched_job(cf, ca)
  1872. Xcb_fun cf;
  1873. Xvoidp ca;
  1874. X{
  1875. X    pjob *p = ALLOC(pjob);
  1876. X
  1877. X    p->cb_fun = cf;
  1878. X    p->cb_closure = ca;
  1879. X
  1880. X    /*
  1881. X     * Now place on wait queue
  1882. X     */
  1883. X    ins_que(&p->hdr, &proc_wait_list);
  1884. X
  1885. X    return p;
  1886. X}
  1887. X
  1888. Xvoid run_task(tf, ta, cf, ca)
  1889. Xtask_fun tf;
  1890. Xvoidp ta;
  1891. Xcb_fun cf;
  1892. Xvoidp ca;
  1893. X{
  1894. X    pjob *p = sched_job(cf, ca);
  1895. X    int mask;
  1896. X
  1897. X    p->wchan = (voidp) p;
  1898. X
  1899. X    mask = sigblock(sigmask(SIGCHLD));
  1900. X
  1901. X    if (p->pid = background()) {
  1902. X        sigsetmask(mask);
  1903. X        return;
  1904. X    }
  1905. X
  1906. X    exit((*tf)(ta));
  1907. X    /* firewall... */
  1908. X    abort();
  1909. X}
  1910. X
  1911. X/*
  1912. X * Schedule a task to be run when woken up
  1913. X */
  1914. Xvoid sched_task(cf, ca, wchan)
  1915. Xcb_fun cf;
  1916. Xvoidp ca;
  1917. Xvoidp wchan;
  1918. X{
  1919. X    /*
  1920. X     * Allocate a new task
  1921. X     */
  1922. X    pjob *p = sched_job(cf, ca);
  1923. X#ifdef DEBUG
  1924. X    /*dlog("sleep(%#x)", wchan);*/
  1925. X#endif
  1926. X    p->wchan = wchan;
  1927. X    p->pid = 0;
  1928. X    bzero((voidp) &p->w, sizeof(p->w));
  1929. X}
  1930. X
  1931. Xstatic void wakeupjob(p)
  1932. Xpjob *p;
  1933. X{
  1934. X    rem_que(&p->hdr);
  1935. X    ins_que(&p->hdr, &proc_list_head);
  1936. X    task_notify_todo++;
  1937. X}
  1938. X
  1939. Xvoid wakeup(wchan)
  1940. Xvoidp wchan;
  1941. X{
  1942. X    pjob *p, *p2;
  1943. X
  1944. X    if (!foreground)
  1945. X        return;
  1946. X
  1947. X#ifdef DEBUG
  1948. X    /*dlog("wakeup(%#x)", wchan);*/
  1949. X#endif
  1950. X    /*
  1951. X     * Can't user ITER() here because
  1952. X     * wakeupjob() juggles the list.
  1953. X     */
  1954. X    for (p = FIRST(pjob, &proc_wait_list);
  1955. X            p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
  1956. X            p = p2) {
  1957. X        if (p->wchan == wchan)
  1958. X            wakeupjob(p);
  1959. X    }
  1960. X}
  1961. X
  1962. Xvoid wakeup_task(rc, term, cl)
  1963. Xint rc;
  1964. Xint term;
  1965. Xvoidp cl;
  1966. X{
  1967. X    wakeup(cl);
  1968. X}
  1969. X
  1970. X/*ARGSUSED*/
  1971. Xvoid sigchld(sig)
  1972. Xint sig;
  1973. X{
  1974. X    union wait w;
  1975. X    int pid;
  1976. X
  1977. X#ifdef SYS5_SIGNALS
  1978. X    if ((pid = wait(&w)) > 0) {
  1979. X#else
  1980. X    while ((pid = wait3(&w, WNOHANG, (union wait *) 0)) > 0) {
  1981. X#endif
  1982. X        pjob *p, *p2;
  1983. X
  1984. X        if (WIFSIGNALED(w))
  1985. X            plog(XLOG_ERROR, "Process %d exited with signal %d",
  1986. X                pid, w.w_termsig);
  1987. X#ifdef DEBUG
  1988. X        else
  1989. X            dlog("Process %d exited with status %d",
  1990. X                pid, w.w_retcode);
  1991. X#endif
  1992. X
  1993. X        for (p = FIRST(pjob, &proc_wait_list);
  1994. X                p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
  1995. X                p = p2) {
  1996. X            if (p->pid == pid) {
  1997. X                p->w = w;
  1998. X                wakeupjob(p);
  1999. X                break;
  2000. X            }
  2001. X        }
  2002. X
  2003. X#ifdef DEBUG
  2004. X        if (p) ; else dlog("can't locate task block for pid %d", pid);
  2005. X#endif
  2006. X    }
  2007. X
  2008. X#ifdef SYS5_SIGNALS
  2009. X    signal(sig, sigchld);
  2010. X#endif
  2011. X    if (select_intr_valid)
  2012. X        longjmp(select_intr, sigchld);
  2013. X}
  2014. X
  2015. X/*
  2016. X * Run any pending tasks.
  2017. X * This must be called with SIGCHLD disabled
  2018. X */
  2019. Xvoid task_notify(P_void)
  2020. X{
  2021. X    /*
  2022. X     * Keep taking the first item off the list and processing it.
  2023. X     *
  2024. X     * Done this way because the the callback can, quite reasonably,
  2025. X     * queue a new task, so no local reference into the list can be
  2026. X     * held here.
  2027. X     */
  2028. X    while (FIRST(pjob, &proc_list_head) != HEAD(pjob, &proc_list_head)) {
  2029. X        pjob *p = FIRST(pjob, &proc_list_head);
  2030. X        rem_que(&p->hdr);
  2031. X        /*
  2032. X         * This job has completed
  2033. X         */
  2034. X        --task_notify_todo;
  2035. X
  2036. X        /*
  2037. X         * Do callback if it exists
  2038. X         */
  2039. X        if (p->cb_fun)
  2040. X            (*p->cb_fun)(p->w.w_retcode,
  2041. X                p->w.w_termsig, p->cb_closure);
  2042. X
  2043. X        free(p);
  2044. X    }
  2045. X}
  2046. END_OF_FILE
  2047. if test 4945 -ne `wc -c <'sched.c'`; then
  2048.     echo shar: \"'sched.c'\" unpacked with wrong size!
  2049. fi
  2050. # end of 'sched.c'
  2051. fi
  2052. echo shar: End of archive 4 \(of 13\).
  2053. cp /dev/null ark4isdone
  2054. MISSING=""
  2055. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  2056.     if test ! -f ark${I}isdone ; then
  2057.     MISSING="${MISSING} ${I}"
  2058.     fi
  2059. done
  2060. if test "${MISSING}" = "" ; then
  2061.     echo You have unpacked all 13 archives.
  2062.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2063. else
  2064.     echo You still need to unpack the following archives:
  2065.     echo "        " ${MISSING}
  2066. fi
  2067. ##  End of shell archive.
  2068. exit 0
  2069. exit 0 # Just in case...
  2070.